'use strict'

import {
  protocol,
  // 浏览器窗口
  BrowserWindow,
  // 主进程
  app,
  Menu,
  ipcMain,
  remote,
  session,
  shell,
  screen
} from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
const path = require('path')

// 菜单
import '@/extrafn/topMenu'

//#region 启动websocket服务
const WebSocket = require('ws');
import { config as wsc } from '@/config/ws.config'
import { wsf, wsfb } from '@/extrafn/websocket_server'
import { findAvailablePort } from '@/extrafn/AvailablePort'

const ws_content = {}

const global_config = {
  win: {
    margin: {
      l: 2,
      r: 2,
      b: 3
    }
  }
}

// 当前活动窗体
const running_state = {
  // 当前子窗体
  currentWin: null,
  // 主体窗体
  mainWin: null,
  // 子窗体数量，创建的窗口id依据
  subWin_num: 0,
  mainWin_num: 0,
  // 使用 ws 向页面发送消息
  sender: {
    newTab: null
  },
  subwin_set: {}
}

function websocketServer(server_name, callBack) {
  findAvailablePort(wsc[server_name].port ? wsc[server_name].port : 8282, port => {
    wsc[server_name].port = port
    console.log('\x1B[44m\x1b[37m\x1b[44m %s \x1b[0m%s', server_name.toUpperCase(), ` 端口 \x1B[36m${port}\x1B[0m 可用`)

    const wss = new WebSocket.Server({
      port: port
    })

    ws_content[server_name] = wss

    wsf[server_name] && wsf[server_name](wss)
    callBack && callBack(wss)
  })
}

// 菜单ws
websocketServer('menu')
// 命令ws
websocketServer('cmd')
//#endregion

//#region 通信

// 提供当前的websocket配置信息
ipcMain.handle('websocket-config', event => {
  return new Promise(resolve => resolve(wsc))
})

// 解决跨域
ipcMain.on('fetchData', async (event, url) => {
  try {
    const response = await fetch(url)
    const data = await response.text()
    event.reply('fetchDataResponse', data)
  } catch (error) {
    console.error(error)
  }
})
//#endregion

//#region 窗体全局变量
const global_tab = {
  current: null,
  tabbar_height: 0
}
//#endregion

const isDevelopment = process.env.NODE_ENV !== 'production'

protocol.registerSchemesAsPrivileged([
  { scheme: 'app', privileges: { secure: true, standard: true } }
])

async function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    frame: false,
    minHeight: 250,
    minWidth: 700,
    // transparent:true,
    webPreferences: {
      nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
      contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
      preload: path.join(__static, 'preload/index.js'),
    }
  })

  if (process.env.WEBPACK_DEV_SERVER_URL) {
    await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
    // if (!process.env.IS_TEST) win.webContents.openDevTools()
  } else {
    createProtocol('app')
    win.loadURL('app://./index.html')
  }

  //#region 监听
  // 缩放
  win.on('resize', setWin)

  win.on('resized', () => setWin)

  function setWin() {
    // 全屏时防止子窗体被拖动
    // if (!win.isMaximized()) {}
    const crt_winpos = win.getPosition()
    const crt_winsize = win.getSize()

    if (running_state.currentWin) {
      running_state.currentWin.setResizable(true)
      running_state.currentWin.setBounds({
        ...subWin_pos(crt_winpos[0], crt_winpos[1]),
        ...subWin_size(crt_winsize[0], crt_winsize[1])
      })
      // 解决移动窗口后子窗体可缩放的问题
      setTimeout(() => running_state.currentWin.setResizable(false))
    }
  }

  //#endregion

  win.children = []
  return win
}

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

app.on('ready', async () => {
  console.log('\x1B[42m 主进程加载完成 \x1B[0m')
  const main_win = await createWindow()
  running_state.mainWin = main_win

  // 创建窗体ws通信服务器

  // 标签ws
  websocketServer('tab', wss => wsfb(wss, (msg, send, error) => {
    let send_msg = 'ok'
    switch (msg.event) {
      case 'connect':
        running_state.sender.newTab = send
        send_msg = null
        break
      case 'new-tab':
        createContainer()
        send_msg = null
        break
      case 'show-current-frame':
        if (!running_state.currentWin || running_state.currentWin.wid != msg.wid) {
          running_state.currentWin ? running_state.currentWin.hide() : null
          running_state.currentWin = running_state.subwin_set[msg.wid]
          running_state.currentWin.show()

          running_state.currentWin.setBounds({
            ...subWin_pos(),
            ...subWin_size()
          })
        }
        send_msg = null
        break
      case 'close-current-frame':
        // 强制关闭
        // https://zhuanlan.zhihu.com/p/269811014
        // running_state.subwin_set[msg.wid].destroy()
        running_state.subwin_set[msg.wid].close()
        delete running_state.subwin_set[msg.wid]
        running_state.currentWin = null
        send_msg = null
        break
      default:
        break;
    }

    send_msg ? send(send_msg) : null
  }))
  // 窗体ws
  websocketServer('frame', wss => wsfb(wss, (msg, send, error) => {
    let send_msg = 'ok'
    switch (msg.event) {
      case 'tabbar-height':
        send_msg = main_win
        global_tab.tabbar_height = msg.msg


        // 设置所有子窗体的大小
        const parentSize = main_win.getSize()

        // 遍历所有的字窗体
        if (running_state.currentWin) {
          running_state.currentWin.setSize(parentSize[0] - 2, Math.ceil(parentSize[1] - msg.msg - 1))
        }
        break;

      case 'set-mainWinPos':
        const bound = msg.msg
        // setPosition在wn设置有缩放的情况下有bug，移动窗口会导致窗口缩放
        main_win.setBounds(bound)

        const sub_bound = {
          ...subWin_pos(bound.x, bound.y),
          ...subWin_size(bound.width, bound.height)
        }

        if (running_state.currentWin) {
          running_state.currentWin.setBounds(sub_bound)
        }
        break

      case 'close_win':
        app.quit()
        break
      case 'min_win':
        main_win.minimize()
        break
      case 'toggle_win':
        toggle_win()

        // 发送当前的窗体状态
        send({
          frameState: main_win.isMaximized() ? 'max' : 'restore'
        })
        send_msg = null;
        break
      default:
        break
    }
    send_msg ? send(send_msg) : null
  }))

  function toggle_win() {
    if (main_win.isMaximized()) {
      main_win.restore()
    } else {
      main_win.maximize()
    }
  }

  function createContainer(url) {
    // 排他，隐藏其它窗口
    main_win.children.forEach(e => {
      if (e && !e.isDestroyed()) {
        e.hide()
      }
    })

    const win = new BrowserWindow({
      parent: main_win,
      frame: false,
      transparent: true,
      // draggable: true,
      // modal: true,
      // autoHideMenuBar: true, //设置窗口菜单栏是否自动隐藏
      resizable: false, // 用户是否可以手动调整窗口大小
      minimizable: false, //是否可以最小化
      minHeight: 0,
      minWidth: 0,
      // transparent:true,
      webPreferences: {
        preload: path.join(__static, 'preload/newTab.js'),
        nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
        contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION
      }
    })

    running_state.currentWin = win;

    // 异步，滞后操作
    setTimeout(() => {
      const wPos = subWin_pos()
      const wSize = subWin_size()

      win.setBounds({
        ...wPos,
        ...wSize
      })
    })


    if (url) {
      win.loadURL(url)
    } else {
      if (process.env.WEBPACK_DEV_SERVER_URL) {
        win.loadURL(process.env.WEBPACK_DEV_SERVER_URL + 'newTab.html')
      } else {
        createProtocol('app')
        win.loadURL('app://./newTab.html')
      }
    }

    // 设为当前标签页内容
    global_tab.current = win
    main_win.children.push(win)

    // 监听will-navigate事件
    win.webContents.on('did-start-navigation', (event, url) => {
      // 阻止默认导航行为
      event.preventDefault();

      // 在这里进行你想要的处理
      // console.log('截获导航:', url);
    })

    // 设置子页面id
    win.wid = `main_${running_state.mainWin_num}sub_${running_state.subWin_num}`
    running_state.subWin_num++

    // 子窗体页面加载完成
    const web = win.webContents


    // 发送新页信息
    running_state.sender.newTab({
      wid: win.wid,
      title: 'about:blank',
      url: 'about:blank'
    })

    web.addListener('did-finish-load', () => {
      // if (!win.isDestroyed()) {
      // }
      running_state.subwin_set[win.wid] = win

      console.log(win.wid, {
        title: web.getTitle(),
        url: web.getURL()
      });
      // 发送新页信息
      running_state.sender.newTab({
        wid: win.wid,
        title: web.getTitle(),
        url: web.getURL()
      })

      // main_win.webContents.send("13123")
      // running_state.mainWin.webContents.send('1232313')
    })

    // 渲染进程中请求创建一个新窗口之前被调用
    // https://blog.csdn.net/weixin_56295520/article/details/131826632
    win.webContents.setWindowOpenHandler(details => {
      if (details.url) {
        createContainer(details.url)
      }
      return { action: 'deny' } // 取消创建新窗口
    })
  }

  app.on('before-quit', event => {
    // do something
    console.log('\x1B[41m electron 主程序即将关闭 \x1B[0m');
    ws_content.menu.close()
    for (let k in ws_content) {
      ws_content[k].close()
      console.log(`端口\x1b[36m ${ws_content[k].options.port} \x1b[0m已释放`)
    }
  })
})


function subWin_pos(x, y) {
  const crt_winpos = x && y ? [x, y] : running_state.mainWin.getPosition()
  return {
    x: Math.ceil(crt_winpos[0] + global_config.win.margin.l),
    y: Math.ceil(crt_winpos[1] + global_tab.tabbar_height)
  }

}
function subWin_size(w, h) {
  const crt_winsize = w && h ? [w, h] : running_state.mainWin.getSize()
  return {
    width: Math.ceil(crt_winsize[0] - global_config.win.margin.l - global_config.win.margin.r),
    height: Math.ceil(crt_winsize[1] - global_tab.tabbar_height - global_config.win.margin.b)
  }
}


if (isDevelopment) {
  if (process.platform === 'win32') {
    process.on('message', (data) => {
      if (data === 'graceful-exit') {
        app.quit()
      }
    })
  } else {
    process.on('SIGTERM', () => {
      app.quit()
    })
  }
}
